home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / Basic / Visual Basic.60 / COMMON / TOOLS / VB / UNSUPPRT / CALENDAR / OFFSCRN.CLS < prev    next >
Encoding:
Visual Basic class definition  |  1997-01-16  |  15.7 KB  |  422 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4. END
  5. Attribute VB_Name = "OffScreenDC"
  6. Attribute VB_GlobalNameSpace = False
  7. Attribute VB_Creatable = False
  8. Attribute VB_PredeclaredId = False
  9. Attribute VB_Exposed = False
  10. '----------------------------------------------------------------------
  11. ' OffScreenDC.cls
  12. '----------------------------------------------------------------------
  13. ' Implementation file for OffScreenDC class
  14. ' This class represents an off screen DC that is useful
  15. ' for enabling flick-free and smooth repainting of things
  16. ' like controls.
  17. '
  18. ' There are also a couple helper methods that do interesting
  19. ' GDI operations like drawing 3d rectangles and fast rectangles
  20. '----------------------------------------------------------------------
  21. ' Copyright (c) 1996, Microsoft Corporation
  22. '              All Rights Reserved
  23. '
  24. ' Information Contained Herin is Proprietary and Confidential
  25. '----------------------------------------------------------------------
  26.  
  27. Option Explicit
  28.  
  29. '======================================================================
  30. ' Public Enumerations
  31. '======================================================================
  32. Public Enum CaptionAlignments
  33.     caCenterCenter
  34.     cacenterleft
  35.     caCenterRight
  36.     caTopCenter
  37.     caTopLeft
  38.     caTopRight
  39.     caBottomCenter
  40.     caBottomLeft
  41.     caBottomright
  42. End Enum
  43.  
  44. Public Enum Appearances
  45.     Raised
  46.     Flat
  47.     Sunken
  48.     Selected
  49. End Enum
  50.  
  51. '======================================================================
  52. ' Private Constants
  53. '======================================================================
  54. Private Const BORDER_WIDTH As Long = 3
  55.  
  56. '======================================================================
  57. ' Private Data Members
  58. '======================================================================
  59. Private mhdcWork As Long        'off-screen HDC
  60. Private mhdcCtl As Long         'actual HDC of the control
  61. Private mhbmpOld As Long        'hBmp of the old bitmap in the off-sceen DC
  62. Private mfntCurrent As IFont    'font to use when drawing text
  63. Private mhfntOld As Long        'hFont of the old font in the off-screen dc
  64.  
  65. Private mcxCtlWidth As Long     'width of the control's surface
  66. Private mcyCtlHeight As Long    'height of the control's surface
  67.  
  68. Private mrgb3DFace As Long      'color to use for the 3d face
  69. Private mrgb3DHighlight As Long 'color to use for the 3d highlight
  70. Private mrgb3DShadow As Long    'color to use for the 3d shadow
  71.  
  72. '======================================================================
  73. ' Initialize and Terminate Events
  74. '======================================================================
  75.  
  76. '----------------------------------------------------------------------
  77. ' Class_Terminate()
  78. '----------------------------------------------------------------------
  79. ' Purpose:  Called when the object is destroyed--do clean-up work
  80. ' Inputs:   None
  81. ' Outputs:  None
  82. '----------------------------------------------------------------------
  83. Private Sub Class_Terminate()
  84.     Dim hBmp As Long
  85.     
  86.     'if our handles are NULL then just get out
  87.     If mhdcWork <> 0 Then
  88.         'select the old font back into the off-screen dc
  89.         SelectObject mhdcWork, mhfntOld
  90.         
  91.         'select the old bitmap back into the off-screen DC
  92.         hBmp = SelectObject(mhdcWork, mhbmpOld)
  93.         
  94.         'delete the bitmap we were using
  95.         DeleteObject hBmp
  96.         
  97.         'and now delete the off-screen DC to totally clean up
  98.         DeleteDC mhdcWork
  99.     End If 'we were initialized
  100.     
  101. End Sub 'Class_Terminate()
  102.  
  103. '======================================================================
  104. ' Public Methods and Properties
  105. '======================================================================
  106.  
  107. '----------------------------------------------------------------------
  108. ' BackColor Get/Let
  109. '----------------------------------------------------------------------
  110. ' Purpose:  To get and let the current background color of the DC
  111. '----------------------------------------------------------------------
  112. Public Property Get BackColor() As Long
  113.     'assert that we are initialized
  114.     Debug.Assert mhdcWork <> 0
  115.     
  116.     'return the current background color
  117.     BackColor = GetBkColor(mhdcWork)
  118. End Property 'BackColor Get
  119.  
  120. Public Property Let BackColor(rgbNew As Long)
  121.     'assert that we are initialized
  122.     Debug.Assert mhdcWork <> 0
  123.     
  124.     'set the new background color
  125.     SetBkColor mhdcWork, rgbNew
  126. End Property 'BackColor Let
  127.  
  128. '----------------------------------------------------------------------
  129. ' TextColor Get/Let
  130. '----------------------------------------------------------------------
  131. ' Purpose:  To get and let the current text color of the DC
  132. '----------------------------------------------------------------------
  133. Public Property Get TextColor() As Long
  134.     'assert that we are initialized
  135.     Debug.Assert mhdcWork <> 0
  136.     
  137.     'return the current Text color
  138.     TextColor = GetTextColor(mhdcWork)
  139. End Property 'TextColor Get
  140.  
  141. Public Property Let TextColor(rgbNew As Long)
  142.     'assert that we are initialized
  143.     Debug.Assert mhdcWork <> 0
  144.     
  145.     'set the new text color
  146.     SetTextColor mhdcWork, rgbNew
  147. End Property 'TextColor Let
  148.  
  149. '----------------------------------------------------------------------
  150. ' Font Get/Set
  151. '----------------------------------------------------------------------
  152. ' Purpose:  To get and set the current font to use on the DC
  153. '----------------------------------------------------------------------
  154. Public Property Get Font() As StdFont
  155.     'just return the reference we currently are holding
  156.     Set Font = mfntCurrent
  157. End Property 'Font Get
  158.  
  159. Public Property Set Font(NewFont As StdFont)
  160.     'make sure we're initialized first
  161.     'must call Initialize before setting the font!
  162.     Debug.Assert (mhdcWork <> 0)
  163.     
  164.     'below we will set a local member variable equal to the
  165.     'object passed in.  Even though the type passed in is a
  166.     'StdFont, our member variable is of type IFont.  A StdFont
  167.     'can be casted (QI) to an IFont, and the IFont interface gives
  168.     'us access to the hFont property, which we need in order to
  169.     'set the current font of the off-screen device context.
  170.         
  171.     'if this is the first time the font is being set,
  172.     'grab the existing hFont handle so we can restore it
  173.     'before deleting the DC
  174.     If mfntCurrent Is Nothing Then
  175.         Set mfntCurrent = NewFont
  176.         mhfntOld = SelectObject(mhdcWork, mfntCurrent.hFont)
  177.     Else
  178.         Set mfntCurrent = NewFont
  179.         
  180.         'if this is being set to Nothing, restore the old font
  181.         If mfntCurrent Is Nothing Then
  182.             SelectObject mhdcWork, mhfntOld
  183.         Else
  184.             SelectObject mhdcWork, mfntCurrent.hFont
  185.         End If 'new font is nothing
  186.         
  187.     End If 'first time setting font
  188.  
  189. End Property 'Font Set
  190.  
  191. '----------------------------------------------------------------------
  192. ' 3D Colors Properties
  193. '----------------------------------------------------------------------
  194. ' Purpose:  To return the RGB values for 3d colors
  195. '----------------------------------------------------------------------
  196. Public Property Get ThreeDFaceColor() As Long
  197.     ThreeDFaceColor = mrgb3DFace
  198. End Property
  199.  
  200. Public Property Get ThreeDHighlightColor() As Long
  201.     ThreeDHighlightColor = mrgb3DHighlight
  202. End Property
  203.  
  204. Public Property Get ThreeDShadowColor() As Long
  205.     ThreeDShadowColor = mrgb3DShadow
  206. End Property
  207.  
  208. '----------------------------------------------------------------------
  209. ' Initialize()
  210. '----------------------------------------------------------------------
  211. ' Purpose:  To initialize the object with the screen DC from which we
  212. '           will create the off-screen DC
  213. ' Inputs:   The user control
  214. ' Outputs:  none
  215. '----------------------------------------------------------------------
  216. Public Sub Initialize(CtlHdc As Long, CtlWidth As Long, CtlHeight As Long)
  217.     Dim hBmp As Long
  218.     
  219.     'assert that the inputs are valid
  220.     'and that we haven't already called Initialize
  221.     Debug.Assert (CtlHdc <> 0)
  222.     Debug.Assert (mhdcWork = 0)
  223.     
  224.     'store the HDC of the control in our private variable
  225.     mhdcCtl = CtlHdc
  226.     
  227.     'capture the width and height of the control
  228.     mcxCtlWidth = CtlWidth
  229.     mcyCtlHeight = CtlHeight
  230.     
  231.     'create the off-sceen DC
  232.     mhdcWork = CreateCompatibleDC(mhdcCtl)
  233.     
  234.     'create a compatible bitmap from the control DC
  235.     'that is the same size as the control itself
  236.     hBmp = CreateCompatibleBitmap(mhdcCtl, mcxCtlWidth, mcyCtlHeight)
  237.     
  238.     'select that new bitmap into the off-screen DC
  239.     'and save the old bitmap handle so we can reselect
  240.     'it back in before we destroy the off-screen DC
  241.     mhbmpOld = SelectObject(mhdcWork, hBmp)
  242. End Sub 'Initialize()
  243.  
  244. '----------------------------------------------------------------------
  245. ' FillRect()
  246. '----------------------------------------------------------------------
  247. ' Purpose:  To fill a rectangle on the off-screen DC with a specified
  248. '           color in a fast way
  249. ' Inputs:   The rectangle to fill and color to use
  250. ' Outputs:  none
  251. '----------------------------------------------------------------------
  252. Public Sub FillRect(nLeft As Long, nTop As Long, nWidth As Long, nHeight As Long, rgbColor As Long, Optional sCaption As String = "", Optional CaptionAlign As CaptionAlignments = caCenterCenter)
  253.     Dim nX As Long              'X for drawing caption text
  254.     Dim nY As Long              'Y for drawing caption text
  255.     Dim rc As RECT              'rect struct to pass to the GDI
  256.     Dim szTextExtent As Size    'pixel size of caption
  257.     
  258.     'assert that we've been initialized already
  259.     'and check the inputs
  260.     Debug.Assert mhdcWork <> 0
  261.     Debug.Assert rgbColor >= 0
  262.     
  263.     'set the back color of the DC to the color desired
  264.     Me.BackColor = rgbColor
  265.     
  266.     'calculate the caption X and Y (centered) if the caption
  267.     'is not an empty string
  268.     If Len(sCaption) > 0 Then
  269.         
  270.         'get the pixel width of the Caption
  271.         GetTextExtentPoint32 mhdcWork, sCaption, Len(sCaption), szTextExtent
  272.         
  273.         'determine the X value based on the alignment chosen
  274.         Select Case CaptionAlign
  275.             Case caCenterCenter, caTopCenter, caBottomCenter
  276.                 nX = ((nWidth - szTextExtent.cx) \ 2) + nLeft
  277.             
  278.             Case caCenterRight, caTopRight, caBottomright
  279.                 nX = nWidth - BORDER_WIDTH - szTextExtent.cx + nLeft
  280.             
  281.             Case cacenterleft, caTopLeft, caBottomLeft
  282.                 nX = nLeft + BORDER_WIDTH
  283.         End Select
  284.         
  285.         'determine the Y value base on the alignment chosen
  286.         Select Case CaptionAlign
  287.             Case caCenterCenter, caCenterRight, cacenterleft
  288.                 nY = ((nHeight - szTextExtent.cy) \ 2) + nTop
  289.                 
  290.             Case caTopCenter, caTopLeft, caTopRight
  291.                 nY = nTop + BORDER_WIDTH
  292.             
  293.             Case caBottomCenter, caBottomLeft, caBottomright
  294.                 nY = nHeight - BORDER_WIDTH - szTextExtent.cy + nTop
  295.                 
  296.         End Select
  297.     End If 'caption is not ""
  298.     
  299.     'assign the input values to the rect struct
  300.     rc.Left = nLeft
  301.     rc.Top = nTop
  302.     rc.Right = nWidth + nLeft
  303.     rc.Bottom = nHeight + nTop
  304.     
  305.     'ExtTextOut is one of the fastest ways to fill a rectangular
  306.     'area on a DC and is used here to fill our rect
  307.     ExtTextOut mhdcWork, nX, nY, ETO_OPAQUE + ETO_CLIPPED, rc, sCaption, Len(sCaption), 0
  308.     
  309. End Sub 'FillRect
  310.  
  311. '----------------------------------------------------------------------
  312. ' Draw3DRect()
  313. '----------------------------------------------------------------------
  314. ' Purpose:  To draw a 3D looking rectangle on the off-screen DC
  315. ' Inputs:   The rectangle to make 3d and optionally a caption to
  316. '           display centered in the rect
  317. ' Outputs:  none
  318. '----------------------------------------------------------------------
  319. Public Sub Draw3DRect(ByVal nLeft As Long, ByVal nTop As Long, ByVal nWidth As Long, ByVal nHeight As Long, Optional sCaption As String = "", Optional CaptionAlign As CaptionAlignments = caCenterCenter, Optional Appearance As Appearances = Raised)
  320.     Dim rgbLowerRight As Long   'color to use for the lower right
  321.     Dim rgbUpperLeft As Long    'color to use for the upper left
  322.     
  323.     'assert that we've been initialized already
  324.     'and check the inputs
  325.     Debug.Assert mhdcWork <> 0
  326.     
  327.     'if we haven't gotten the system colors for 3d effects
  328.     'get them first
  329.     If mrgb3DFace = 0 Then
  330.         mrgb3DFace = GetSysColor(COLOR_BTNFACE)
  331.         mrgb3DHighlight = GetSysColor(COLOR_BTNHIGHLIGHT)
  332.         mrgb3DShadow = GetSysColor(COLOR_BTNSHADOW)
  333.     End If
  334.             
  335.     'set the lower-right and upper-left colors based on the
  336.     'desired appearance
  337.     Select Case Appearance
  338.         Case Flat
  339.             rgbLowerRight = mrgb3DShadow
  340.             rgbUpperLeft = mrgb3DShadow
  341.         
  342.         Case Raised
  343.             rgbLowerRight = mrgb3DShadow
  344.             rgbUpperLeft = mrgb3DHighlight
  345.             
  346.         Case Sunken
  347.             rgbLowerRight = mrgb3DHighlight
  348.             rgbUpperLeft = mrgb3DShadow
  349.         
  350.         Case Selected
  351.             rgbLowerRight = mrgb3DHighlight
  352.             rgbUpperLeft = vbBlack
  353.         
  354.     End Select
  355.     
  356.     'fill the rect with the shadow color (or hightlight if sunken)
  357.     Me.FillRect nLeft, nTop, nWidth, nHeight, rgbLowerRight
  358.     
  359.     'now pull the right and bottom edges in by 1 pixel
  360.     nWidth = nWidth - 1
  361.     nHeight = nHeight - 1
  362.     
  363.     'fill the rect with the 3d highlight color (or shadow if sunken)
  364.     Me.FillRect nLeft, nTop, nWidth, nHeight, rgbUpperLeft
  365.     
  366.     'finally pull in the left and top edges by 1 pixel
  367.     nLeft = nLeft + 1
  368.     nTop = nTop + 1
  369.     nWidth = nWidth - 1
  370.     nHeight = nHeight - 1
  371.     
  372.     'change the color to the 3d face color
  373.     'and fill the rect passing the desired caption
  374.     Me.FillRect nLeft, nTop, nWidth, nHeight, mrgb3DFace, sCaption, CaptionAlign
  375.  
  376.     'if the appearance setting was Selected, invert the rect
  377.     If Appearance = Selected Then
  378.         InvertRect nLeft, nTop, nWidth, nHeight
  379.     End If 'appearance = selected
  380.     
  381. End Sub 'Draw3dRect
  382.  
  383. '----------------------------------------------------------------------
  384. ' InvertRect()
  385. '----------------------------------------------------------------------
  386. ' Purpose:  To invert a particular rect on the bitmap
  387. ' Inputs:   The area to invert
  388. ' Outputs:  none
  389. '----------------------------------------------------------------------
  390. Public Sub InvertRect(nLeft As Long, nTop As Long, nWidth As Long, nHeight As Long)
  391.     Dim rc As RECT
  392.     
  393.     rc.Left = nLeft
  394.     rc.Top = nTop
  395.     rc.Right = nLeft + nWidth
  396.     rc.Bottom = nTop + nHeight
  397.     
  398.     Utils.InvertRect mhdcWork, rc
  399. End Sub 'InvertRect()
  400.  
  401. '----------------------------------------------------------------------
  402. ' BlastToScreen()
  403. '----------------------------------------------------------------------
  404. ' Purpose:  Blasts the contents of the off-screen DC to the control's
  405. '           on-screen surface
  406. ' Inputs:   none
  407. ' Outputs:  none
  408. '----------------------------------------------------------------------
  409. Public Sub BlastToScreen(Optional Left As Long = 0, Optional Top As Long = 0, Optional Width As Long = -1, Optional Height As Long = -1)
  410.     If Width = -1 Then Width = mcxCtlWidth
  411.     If Height = -1 Then Height = mcyCtlHeight
  412.     
  413.     'use bitblt to blast the contents of the off-screen dc to the control
  414.     BitBlt mhdcCtl, Left, Top, Width, Height, mhdcWork, _
  415.             Left, Top, SRCCOPY
  416. End Sub 'BlastToScreen()
  417.  
  418. '======================================================================
  419. ' Private Helper Methods
  420. '======================================================================
  421.  
  422.